import threading
import socketserver
import logging
import datetime

FORMAT = "%(asctime)s %(processName)s %(process)s %(threadName)s %(thread)s %(message)s"
logging.basicConfig(level=logging.INFO,format=FORMAT,datefmt='%Y%m%d-%H:%M:%S')


class ChatHandler(socketserver.StreamRequestHandler):
    def setup(self,clients={}):
        super().setup()
        self.event = threading.Event()
        self.__clients = clients
        self.__lock = threading.Lock()

    def handle(self):
        super().handle()
        logging.info(self.request)
        logging.info(self.rfile)
        logging.info(self.wfile)
        with self.__lock:
            self.__clients[self.client_address] = self.wfile
            print(self.__clients)
        while not self.event.is_set():
            try:
                data = self.rfile.readline().strip()
            except Exception as e:
                logging.error(e)
                data = b'quit'
            if data == b'quit':
                with self.__lock:
                    self.__clients.pop(self.client_address)
                self.request.close()
                break
            logging.info(data)
            msg = '{} From {}:{} msg={}'.format(datetime.datetime.now().strftime('%Y%m%d-%H:%M:%S'),*self.client_address,data.decode()).encode()
            logging.info(msg)
            # self.wfile.write(msg)
            for f in self.__clients.values():
                f.write(msg)

    def finish(self):
        super().finish()
        self.event.set()

addr = '127.0.0.1',9998
chatserver = socketserver.ThreadingTCPServer(addr,ChatHandler)
threading.Thread(target=chatserver.serve_forever,name='chatserver',daemon=True).start()
chatserver.daemon_threads = True

while True:
    cmd = input('>>>').strip()
    if cmd == 'quit':
        chatserver.server_close()
        break

    print(threading.enumerate())